import { Injectable,Inject } from '@angular/core';
import {HttpClient,HttpHeaders} from "@angular/common/http";
import {TaskList} from "../domain"
import {Observable,from,pipe, concat} from "rxjs";

import {map,mergeMap,count,switchMap,mapTo,reduce} from "rxjs/operators";

@Injectable({
  providedIn: 'root'
})
export class TaskListService {

  private readonly domain = 'taskLists';
  private headers = new HttpHeaders({
    'content-Type': 'application/json'
  })
  constructor(private http:HttpClient,@Inject('BASE_CONFIG') private config) { }
  //post
  add(taskList:TaskList):Observable<TaskList>{
    // taskList.id = null;
    const uri = `${this.config.uri}/${this.domain}`;
    return this.http.post<TaskList>(uri,JSON.stringify(taskList),{headers:this.headers}).pipe(
      map(res=>res)
    )
  }
  //post
  update(taskList:TaskList):Observable<TaskList>{
    const uri = `${this.config.uri}/${this.domain}/${taskList.id}`;
    const toUpdate = {
      name:taskList.name,
    };
    return this.http.patch<TaskList>(uri,JSON.stringify(toUpdate),{headers:this.headers}).pipe(
      map(res=>res)
    )
  }
  //delete
  del(taskList:TaskList): Observable<TaskList>{
    const uri = `${this.config.uri}/taskLists/${taskList.id}`;
    return this.http.delete(uri).pipe(
      mapTo(taskList)
    );
  }
  //get
  getTaskLists(projectId:string):Observable<TaskList[]>{
    const uri = `${this.config.uri}/${this.domain}`;
    return this.http.get(uri,{params:{'projectId':projectId}}).pipe(
      map(res =>res  as TaskList[])
    );
  }
  swapOrder(src:TaskList,target:TaskList):Observable<TaskList[]>{
    const dragUri = `${this.config.uri}/${this.domain}/${src.id}`;
    const dropUri = `${this.config.uri}/${this.domain}/${target.id}`;
    const drag$ = this.http.patch(dragUri,JSON.stringify({order:target.order}),{headers:this.headers}).pipe(
      map(res=>res)
    );
    const drop$ = this.http.patch(dropUri,JSON.stringify({order:target.order}),{headers:this.headers}).pipe(
      map(res=>res)
    );
    return concat(drag$, drop$).pipe(
      reduce((arrs:TaskList[],list:TaskList)=>[...arrs,list],[])
    )
    ;
  }
}
